package net.comfycastle.musicplayer;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;

public class MusicUtility {
	/** 에러를 나타내는 문자열 */
	private final static String ERROR = "error";
	
	///////////
	//////////
	/////////   variable
	
	/** 음악 서비스 인터페이스 객체 */
	private static IMusicService mMService = null;
	
	/** 현재 재생중인 노래 목록의 종류 값. PlayActivity가 재실행될 때를 대비해 보관한다. */
	private static String  sKey;
	/** 현재 재생중인 노래 목록의 종류명 값. PlayActivity가 재실행될 때를 대비해 보관한다. */
	private static String  sValue;
	/** 현재 재생중인 노래 목록의 아티스트 값. PlayActivity가 재실행될 때를 대비해 보관한다. */
	private static String  sArtist;
	/** 현재 재생중인 노래 목록의 앨범아티스트인가 아닌가 값. PlayActivity가 재실행될 때를 대비해 보관한다. */
	private static boolean sIsAA;
	
	///////////
	//////////
	/////////   setter
	
	/**
	* 현재 재생 중인 노래 목록의 종류를 저장한다.
	* @param kind 노래 목록 분류 종류
	*/
	public static void logKeyOfPlaylist(String kind) {
		sKey = kind;
	} // end setKindOfList
	
	/**
	* 현재 재생 중인 노래 목록의 세부 분류를 저장한다.
	* @param name 노래 목록의 세부 분류
	*/
	public static void logValueOfPlaylist(String name) {
		sValue = name;
	} // end setNameOfList
	
	/**
	* 현재 재생 중인 노래 목록의 아티스트를 저장한다.
	* @param artist 노래 목록의 아티스트
	*/
	public static void logArtistOfPlaylist(String artist) {
		sArtist = artist;
	} // end setArtistOfList
	
	/**
	* 현재 재생 중인 노래 목록의 아티스트가 앨범 아티스트인지 아닌지 저장한다.
	* @param isAA 앨범 아티스트인지 여부
	*/
	public static void logIsAAOfPlaylist(boolean isAA) {
		sIsAA = isAA;
	} // end setIsAAOfList
	
	/**
	 * 노래가 재생 중이었는지 저장한다.
	 * 음악 서비스 래퍼 메서드
	 */
	public static void setWasPlaying() {
		/********/Log.i("MPApp", "setWasPlaying");
		try {
			if(mMService != null) {
				mMService.setWasPlaying();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end setWasPlaying
	
	///////////
	//////////
	/////////   getter

	/**
	* 현재 재생 중인 노래 목록의 종류르 얻는다.
	* @return 노래 목록의 종류
	*/
	public static String getKeyOfPlaylist() {
		return sKey;
	} // end getKindOfList
	
	/**
	* 현재 재생 중인 노래 목록의 세부 분류를 얻는다.
	* @return 노래 목록의 세부 분류
	*/
	public static String getValueOfPlaylist() {
		return sValue;
	} // end getNameOfList
	
	/**
	* 현재 재생 중인 노래 목록의 아티스트를 얻는다.
	* @return 노래 목록의 아티스트
	*/
	public static String getArtistOfPlaylist() {
		return sArtist;
	} // end getArtistOfList
	
	/**
	 * 현재 재생 중인 노래 목록의 아티스트가 앨범 아티스트인지 아닌지를 얻는다.
	 * @return 앨범 아티스트인지 여부
	 */
	public static boolean getIsAAOfPlaylist() {
		return sIsAA;
	} // end getIsAAOfList	
	
	
	public static boolean isBindedService() {
		if(mMService == null) {
			return false;
		} else {
			return true;
		} // end if
	} // end isBindedService
	
	/**
	 * 노래의 제목을 얻어 온다.
	 * 음악 서비스 래퍼 메서드
	 * @return 노래 제목
	 */
	public static String getTitle() {
		/********/Log.i("MPApp", "getTitle");
		try {
			if(mMService != null) {
				return mMService.getTitle();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return ERROR;
	} // end getTitle
	
	/**
	 * 노래의 앨범 제목을 얻어 온다.
	 * 음악 서비스 래퍼 메서드
	 * @return 앨범 제목
	 */
	public static String getAlbum() {
		/********/Log.i("MPApp", "getAlbum");
		try {
			if(mMService != null) {
				return mMService.getAlbum();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return ERROR;
	} // getAlbum
	
	/**
	 * 노래의 아티스트를 얻어 온다.
	 * 음악 서비스 래퍼 메서드
	 * @return 노래의 아티스트
	 */
	public static String getArtist() {
		/********/Log.i("MPApp", "getArtist");
		try {
			if(mMService != null) {
				return mMService.getArtist();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return ERROR;
	} // end getArtist
	
	/**
	 * 노래의 총 재생 시간을 얻어 온다.
	 * 음악 서비스 래퍼 메서드
	 * @return 총 재생 시간
	 */
	public static int getDuration() {
		/********/Log.i("MPApp", "getDuration");
		try {
			if(mMService != null) {
				return mMService.getDuration();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return 0;
	} // end getDuration
	
	/**
	 * 노래의 재생 진행 정도를 얻어온다.
	 * 음악 서비스 래퍼 메서드
	 * @return 노래의 재생 진행 정도
	 */
	public static int getProgress() {
		/********/Log.i("MPApp", "getProgress");
		try {
			if(mMService != null) {
				return mMService.getProgress();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return 0;
	} // end getProgress
	
	/**
	 * 노래 재생 준비가 되었는지 확인한다
	 * 음악 서비스 래퍼 메서드
	 * @return 준비가 되었으면 true, 아니면 false
	 */
	public static boolean isReady() {
		/********/Log.i("MPApp", "isReady");
		try {
			if(mMService != null) {
				return mMService.isReady();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return false;
	} // end isReady
	
	/**
	 * 노래가 재생 중인지 확인한다.
	 * 음악 서비스 래퍼 메서드
	 * 왜인지 RemoteException을 catch하면 런타임에러를 낸다. 왜?
	 * @return 재생 중이면 true, 아니면 false
	 */
	public static boolean isPlaying() {
		/********/Log.i("MPApp", "isPlaying");
		try {
			if(mMService != null) {
				return mMService.isPlaying();
			}
		} catch(Exception e) { /*********/
			e.printStackTrace();
		} // end try-catch
		
		return false;
	} // end isPlaying
	
	/**
	 * 노래가 재생 중이었는지 확인한다.
	 * 음악 서비스 래퍼 메서드
	 * @return 재생 중이었으면 true, 아니면 false
	 */
	public static boolean wasPlaying() {
		/********/Log.i("MPApp", "wasPlaying");
		try {
			if(mMService != null) {
				return mMService.wasPlaying();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return false;
	} // wasPlaying
	
	/**
	 * 랜덤 재생 중이었는지 확인한다.
	 * 음악 서비스 래퍼 메서드
	 * @return 랜덤 재생이었으면 true, 아니면 false
	 */
	public static boolean isRandom() {
		/********/Log.i("MPApp", "isRandom");
		try {
			if(mMService != null) {
				return mMService.isRandom();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return false;
	} // end isRandom
	
	/**
	 * 반복 재생 상태를 확인한다.
	 * 음악 서비스 래퍼 메서드
	 * @return MusicService.REPEAT 참고
	 */
	public static MusicService.REPEAT getRepeatState() {
		/********/Log.i("MPApp", "getRepeatState");
		try {
			if(mMService != null) {
				switch(mMService.getRepeatState()) {
				case 0:
					return MusicService.REPEAT.NONE;
				case 1:
					return MusicService.REPEAT.ONE;
				case 2:
					return MusicService.REPEAT.LIST;
				} // end switch
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
		
		return MusicService.REPEAT.NONE;
	} // end getRepeatState
	
	///////////
	//////////
	/////////   methods
	
	/**
	 * 음악 서비스 인터페이스를 얻는다.
	 * @param context 인터페이스를 얻을 컨텍스트
	 */
	public static void bindMusicService(Context context) {
		/********/Log.i("MPApp", "bindMusicService");
		Intent intent = new Intent(context, MusicService.class);
		context.bindService(intent, sSrvConn, Context.BIND_AUTO_CREATE);
	} // end bindMusicService
	
	/**
	 * 음악 서비스의 인터페이스를 해제한다.
	 */
	public static void unbindMusicService(Context context) {
		/********/Log.i("MPApp", "unbindMusicService");
		context.unbindService(sSrvConn);
	} // end unbindMusicService
	
	/**
	 * 노래를 재생한다.
	 * 음악 서비스 래퍼 메서드
	 */
	public static void play() {
		/********/Log.i("MPApp", "play");
		try {
			if(mMService != null) {
				mMService.play();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end play
	
	/**
	 * 노래를 일시 정지한다.
	 * 음악 서비스 래퍼 메서드
	 */
	public static void pause() {
		/********/Log.i("MPApp", "pause");
		try {
			if(mMService != null) {
				mMService.pause();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end pause
	
	/**
	 * 노래 재생을 정지한다.
	 * 음악 서비스 래퍼 메서드
	 */
	public static void stop() {
		/********/Log.i("MPApp", "stop");
		try {
			if(mMService != null) {
				mMService.stop();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end stop
	
	/**
	 * 음악 재생 순서를 다음 곡으로 넘긴다.
	 * 음악 서비스 래퍼 메서드
	 */
	public static void next() {
		/********/Log.i("MPApp", "next");
		try {
			if(mMService != null) {
				mMService.next();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end next
	
	/**
	 * 음악 재생 순서를 이전 곡으로 넘긴다.
	 * 음악 서비스 래퍼 메서드
	 */
	public static void prev() {
		/********/Log.i("MPApp", "prev");
		try {
			if(mMService != null) {
				mMService.prev();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end prev
	
	/**
	 * 재생되는 노래 지점을 조정한다.
	 * 음악 서비스 래퍼 메서드
	 * @param msec 조정될 재생 중인 노래 지점 (millisecond)
	 */
	public static void seekTo(int msec) {
		/********/Log.i("MPApp", "seekTo");
		try {
			if(mMService != null) {
				mMService.seekTo(msec);
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end seekTo
	
	public static void toggleRandom() {
		/********/Log.i("MPApp", "toggleRandom");
		try {
			if(mMService != null) {
				mMService.toggleRandom();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end seekTo
	
	public static void toggleRepeat() {
		/********/Log.i("MPApp", "toggleRepeat");
		try {
			if(mMService != null) {
				mMService.toggleRepeat();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end seekTo
	
	/**
	 * 노래가 재생 중이라는 통지를 설정한다.
	 */
	public static void setNotification() {
		/********/Log.i("MPApp", "setNotification");
		try {
			if(mMService != null) {
				mMService.setNotification();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end setNotification
	
	/**
	 * 노래가 재생 중이라는 통지를 해제한다.
	 */
	public static void cancelNotification() {
		/********/Log.i("MPApp", "cancelNotification");
		try {
			if(mMService != null) {
				mMService.cancelNotification();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end cancelNotification
	
	/**
	 * 서비스를 다 사용햇음을 서비스에 알린다.
	 * 어플리케이션이 종료되는 데 노래가 재생 중이라 서비스를 정상적으로 종료할 수 없을 때 실행한다.
	 */
	public static void finishService() {
		/********/Log.i("MPApp", "finishService");
		try {
			if(mMService != null) {
				mMService.finish();
			}
		} catch(Exception e) {
			e.printStackTrace();
		} // end try-catch
	} // end finishService
	
	/**
	 * 종류와 종류명을 갖고 노래의 위치 정보 (목록 정보) 를 만드는 정적 메서드
	 * @param kind 노래 분류 종류
	 * @param name 노래 분류 종류명
	 * @return 목록 정보 문자열
	 */
	public static String makeWhere(String kind, String name) {
		/********/Log.i("MPApp", "makeWhere");
		if(kind.equals("")) {
			return null;
		} // end if
		
		name = name.replace("'", "''");
		return kind + "='" + name +"'";
	} // end makeWhere
	
	/**
	 * 종류와 종류명을 갖고 노래의 위치 정보 (목록 정보) 를 만드는 정적 메서드
	 * @param kind 노래 분류 종류
	 * @param name 노래 분류 종류명
	 * @param artist 노래의 아티스트
	 * @param isAA 앨범 아티스트인가 아닌가
	 * @return
	 */
	public static String makeWhere(String kind, String name, String artist, boolean isAA) {
		/********/Log.i("MPApp", "makeWhere");
		String where = makeWhere(kind, name) + " AND "; 
		
		artist = artist.replace("'", "''");
		
		if(isAA) {
	    	where += MPApp.TAG_ALBUMARTIST;
		} else {
	    	where += MPApp.TAG_ARTIST;
		} // end if
		
		where += "='" + artist + "'";
		
		return where;
	} // end makeWhere
	
	///////////
	//////////
	/////////   event listener & callback method
	
	/**
	* 서비스를 바인딩할 때의 이벤트 리스너 인터페이스
	*/
	static ServiceConnection sSrvConn = new ServiceConnection() {
		/**
		 * 서비스가 연결될 때의 콜백 메서드
		 */
		public void onServiceConnected(ComponentName className, IBinder binder) {
			/********/Log.i("MPApp", "onServiceConnected");
			mMService = IMusicService.Stub.asInterface(binder);
		} // end onServiceConnected
		
		/**
		 * 서비스와의 연결이 끊길 때의 콜백 메서드
		 */
		public void onServiceDisconnected(ComponentName className) {
			/********/Log.i("MPApp", "onServiceDisconnected");
			mMService = null;
		} // end onServiceDisconnected
	}; // end mSrvConn
}
